﻿using System;
using System.Collections.Generic;
using System.Linq;
using CharacterCreation.Data;

namespace CharacterCreation.Business {
    public class Repository<ViewModel, Model> : IRepository<ViewModel> 
        where ViewModel : new() 
        where Model : new() {

        private DataContext context = new DataContext();

        public Repository() {
            new MetaDataStore().AddTableDefinition<Model>();
        }

        public virtual void Add(ViewModel viewModel) {
            context.Insert<Model>(ObjectMapper.Parse<ViewModel, Model>(viewModel));
        }

        public virtual void Add(IEnumerable<ViewModel> viewModels)
        {
            context.Insert(viewModels.Select(v => ObjectMapper.Parse<ViewModel, Model>(v)));
        }

        public virtual IEnumerable<ViewModel> Get()
        {
            return context.Get<Model>()
                .Select(s => ObjectMapper.Parse<Model, ViewModel>(s))
                .ToList();
        }

        public virtual IEnumerable<ViewModel> Get(string where = "")
        {
            return context.Get<Model>(where, string.Empty)
                .Select(s => ObjectMapper.Parse<Model, ViewModel>(s))
                .ToList();
        }

        public virtual IEnumerable<ViewModel> Get(string where = "", string orderby = "")
        {
            return context.Get<Model>(where, orderby)
                .Select(s => ObjectMapper.Parse<Model, ViewModel>(s))
                .ToList();
        }

        public virtual ViewModel Get(Guid id) {
            return ObjectMapper.Parse<Model, ViewModel>(context.Get<Model>(id));
        }

        public virtual void Delete(Guid id) {
            context.Delete<Model>(id);
        }

        public virtual void Update(ViewModel entity) {
            Model target = ObjectMapper.Parse<ViewModel, Model>(entity);

            string[] properties = typeof(ViewModel).GetProperties()
                .Where(p => typeof(Model).GetProperty(p.Name) != null)
                .Where(p => p.Name != "Id")
                .Select(p => p.Name)
                .ToArray();

            context.Update<Model>(target, properties);
        }
    }
}
